"""
性能监控仪表板服务
集成性能监控仪表板到MAESS系统主流程中
"""

import asyncio
from typing import Dict, Any, Optional
from datetime import datetime, timedelta
from loguru import logger

from monitoring.performance_dashboard import PerformanceDashboard, MetricsCollector
from monitoring.performance_dashboard import MetricsCollector, PerformanceDashboard
from app.core.config import settings
from app.core.redis_client import get_redis_client
from utils.logger import Logger


class PerformanceDashboardService:
    """性能监控仪表板服务"""
    
    def __init__(self):
        self.dashboard: Optional[PerformanceDashboard] = None
        self.metrics_collector: Optional[MetricsCollector] = None
        self.is_initialized = False
        self.is_running = False
        self.update_task: Optional[asyncio.Task] = None
        self.redis_client = None
        
    async def initialize(self):
        """初始化性能监控仪表板服务"""
        if self.is_initialized:
            return
            
        try:
            logger.info("🚀 初始化性能监控仪表板服务...")
            
            # 获取Redis客户端
            self.redis_client = get_redis_client()
            
            # 创建指标收集器
            self.metrics_collector = MetricsCollector()
            
            # 创建性能监控仪表板
            self.dashboard = PerformanceDashboard(
                host=settings.PERFORMANCE_DASHBOARD_HOST,
                port=settings.PERFORMANCE_DASHBOARD_PORT
            )
            
            self.is_initialized = True
            logger.info("✅ 性能监控仪表板服务初始化完成")
            
        except Exception as e:
            logger.error(f"❌ 性能监控仪表板服务初始化失败: {e}")
            raise
    
    async def start(self):
        """启动性能监控仪表板服务"""
        if not self.is_initialized:
            await self.initialize()
            
        if self.is_running:
            logger.warning("性能监控仪表板服务已在运行中")
            return
            
        try:
            logger.info("🚀 启动性能监控仪表板服务...")
            
            # 启动仪表板
            await self.dashboard.start()
            
            # 启动后台指标更新任务
            self.update_task = asyncio.create_task(self._metrics_update_loop())
            
            self.is_running = True
            logger.info(f"✅ 性能监控仪表板服务启动完成 - http://{settings.PERFORMANCE_DASHBOARD_HOST}:{settings.PERFORMANCE_DASHBOARD_PORT}")
            
        except Exception as e:
            logger.error(f"❌ 性能监控仪表板服务启动失败: {e}")
            raise
    
    async def stop(self):
        """停止服务"""
        try:
            logger.info("正在停止性能监控仪表板服务...")
            
            # 停止后台任务
            if self.update_task and not self.update_task.done():
                self.update_task.cancel()
                try:
                    await self.update_task
                except asyncio.CancelledError:
                    pass
            
            # 停止仪表板
            if self.dashboard:
                await self.dashboard.stop()
                self.dashboard = None
            
            # 注意：MetricsCollector没有stop方法，所以移除这行
            # if self.metrics_collector:
            #     await self.metrics_collector.stop()
            
            logger.info("✅ 性能监控仪表板服务已停止")
            
        except Exception as e:
            logger.error(f"❌ 停止性能监控仪表板服务失败: {e}")
            raise
    
    async def _metrics_update_loop(self):
        """后台指标更新循环"""
        logger.info("📊 启动后台指标更新循环...")
        
        try:
            while self.is_running:
                try:
                    # 收集系统指标
                    await self._collect_system_metrics()
                    
                    # 收集应用指标
                    await self._collect_application_metrics()
                    
                    # 收集智能体指标
                    await self._collect_agent_metrics()
                    
                    # 等待下一个收集周期
                    await asyncio.sleep(settings.MONITORING_COLLECTION_INTERVAL)
                    
                except asyncio.CancelledError:
                    logger.info("后台指标更新循环已取消")
                    break
                except Exception as e:
                    logger.error(f"指标更新循环异常: {e}")
                    await asyncio.sleep(5)  # 出错后等待5秒重试
                    
        except Exception as e:
            logger.error(f"后台指标更新循环失败: {e}")
    
    async def _collect_system_metrics(self):
        """收集系统级指标"""
        try:
            # 获取系统信息
            system_info = await self._get_system_info()
            
            # 推送系统指标
            if self.metrics_collector:
                self.metrics_collector.push_metrics({
                    "cpu_usage": system_info.get("cpu_usage", 0),
                    "memory_usage": system_info.get("memory_usage", 0),
                    "disk_io": system_info.get("disk_usage", 0),
                    "network_io": system_info.get("network_io", 0)
                })
                
        except Exception as e:
            logger.error(f"收集系统指标失败: {e}")
    
    async def _collect_application_metrics(self):
        """收集应用级指标"""
        try:
            # 获取应用统计信息
            app_stats = await self._get_application_stats()
            
            # 推送应用指标
            if self.metrics_collector:
                self.metrics_collector.push_metrics({
                    "throughput_rps": app_stats.get("throughput_rps", 0),
                    "error_rate": (app_stats.get("error_requests", 0) / max(app_stats.get("total_requests", 1), 1)) * 100,
                    "response_time": app_stats.get("response_time_p95", 0)
                })
                
        except Exception as e:
            logger.error(f"收集应用指标失败: {e}")
    
    async def _collect_agent_metrics(self):
        """收集智能体指标"""
        try:
            # 获取智能体统计信息
            agent_stats = await self._get_agent_stats()
            
            # 推送智能体指标
            if self.metrics_collector:
                # 计算成功率
                total_tasks = max(agent_stats.get("total_tasks", 0), 1)
                success_rate = (agent_stats.get("successful_tasks", 0) / total_tasks) * 100
                
                self.metrics_collector.push_metrics({
                    "throughput_rps": agent_stats.get("total_tasks", 0) / 60,  # 假设每分钟的任务数
                    "error_rate": (agent_stats.get("failed_tasks", 0) / total_tasks) * 100,
                    "response_time": 100  # 默认值，可以根据实际情况调整
                })
                
        except Exception as e:
            logger.error(f"收集智能体指标失败: {e}")
    
    async def _get_system_info(self) -> Dict[str, Any]:
        """获取系统信息"""
        try:
            import psutil
            
            # CPU使用率
            cpu_usage = psutil.cpu_percent(interval=1)
            
            # 内存使用率
            memory = psutil.virtual_memory()
            memory_usage = memory.percent
            
            # 磁盘使用率
            disk = psutil.disk_usage('/')
            disk_usage = (disk.used / disk.total) * 100
            
            # 网络IO
            network_io = psutil.net_io_counters().bytes_sent + psutil.net_io_counters().bytes_recv
            
            return {
                "cpu_usage": cpu_usage,
                "memory_usage": memory_usage,
                "disk_usage": disk_usage,
                "network_io": network_io,
                "timestamp": datetime.now().isoformat()
            }
            
        except Exception as e:
            logger.error(f"获取系统信息失败: {e}")
            return {
                "cpu_usage": 0,
                "memory_usage": 0,
                "disk_usage": 0,
                "network_io": 0,
                "timestamp": datetime.now().isoformat()
            }
    
    async def _get_application_stats(self) -> Dict[str, Any]:
        """获取应用统计信息"""
        try:
            # 从Redis获取应用统计
            if self.redis_client:
                total_requests = int(await self.redis_client.get("app:requests:total") or 0)
                successful_requests = int(await self.redis_client.get("app:requests:success") or 0)
                error_requests = int(await self.redis_client.get("app:requests:error") or 0)
                response_time_p95 = float(await self.redis_client.get("app:response:time:p95") or 0)
                throughput_rps = float(await self.redis_client.get("app:throughput:rps") or 0)
                active_users = int(await self.redis_client.get("app:active:users") or 0)
                active_sessions = int(await self.redis_client.get("app:active:sessions") or 0)
                
                return {
                    "total_requests": total_requests,
                    "successful_requests": successful_requests,
                    "error_requests": error_requests,
                    "response_time_p95": response_time_p95,
                    "throughput_rps": throughput_rps,
                    "active_users": active_users,
                    "active_sessions": active_sessions
                }
            
            return {
                "total_requests": 0,
                "successful_requests": 0,
                "error_requests": 0,
                "response_time_p95": 0,
                "throughput_rps": 0,
                "active_users": 0,
                "active_sessions": 0
            }
            
        except Exception as e:
            logger.error(f"获取应用统计信息失败: {e}")
            return {
                "total_requests": 0,
                "successful_requests": 0,
                "error_requests": 0,
                "response_time_p95": 0,
                "throughput_rps": 0,
                "active_users": 0,
                "active_sessions": 0
            }
    
    async def _get_agent_stats(self) -> Dict[str, Any]:
        """获取智能体统计信息"""
        try:
            # 从Redis获取智能体统计
            if self.redis_client:
                total_agents = int(await self.redis_client.get("agent:total:count") or 0)
                healthy_agents = int(await self.redis_client.get("agent:healthy:count") or 0)
                busy_agents = int(await self.redis_client.get("agent:busy:count") or 0)
                failed_agents = int(await self.redis_client.get("agent:failed:count") or 0)
                total_tasks = int(await self.redis_client.get("agent:tasks:total") or 0)
                successful_tasks = int(await self.redis_client.get("agent:tasks:success") or 0)
                failed_tasks = int(await self.redis_client.get("agent:tasks:failed") or 0)
                
                return {
                    "total_agents": total_agents,
                    "healthy_agents": healthy_agents,
                    "busy_agents": busy_agents,
                    "failed_agents": failed_agents,
                    "total_tasks": total_tasks,
                    "successful_tasks": successful_tasks,
                    "failed_tasks": failed_tasks
                }
            
            return {
                "total_agents": 0,
                "healthy_agents": 0,
                "busy_agents": 0,
                "failed_agents": 0,
                "total_tasks": 0,
                "successful_tasks": 0,
                "failed_tasks": 0
            }
            
        except Exception as e:
            logger.error(f"获取智能体统计信息失败: {e}")
            return {
                "total_agents": 0,
                "healthy_agents": 0,
                "busy_agents": 0,
                "failed_agents": 0,
                "total_tasks": 0,
                "successful_tasks": 0,
                "failed_tasks": 0
            }
    
    def get_dashboard_url(self) -> str:
        """获取仪表板访问URL"""
        if self.dashboard and self.is_running:
            return f"http://{settings.PERFORMANCE_DASHBOARD_HOST}:{settings.PERFORMANCE_DASHBOARD_PORT}"
        return ""
    
    async def get_current_metrics(self) -> Dict[str, Any]:
        """获取当前指标数据"""
        if not self.is_running or not self.metrics_collector:
            return {}
            
        try:
            metrics = await self.metrics_collector.get_metrics(limit=100)
            return {
                "metrics": [metric.__dict__ for metric in metrics],
                "dashboard_url": self.get_dashboard_url(),
                "is_running": self.is_running,
                "last_update": datetime.now().isoformat()
            }
        except Exception as e:
            logger.error(f"获取当前指标失败: {e}")
            return {
                "error": str(e),
                "dashboard_url": self.get_dashboard_url(),
                "is_running": self.is_running
            }
    
    async def health_check(self) -> bool:
        """健康检查"""
        try:
            if not self.is_initialized or not self.is_running:
                return False
            
            # 检查仪表板服务状态
            if self.dashboard:
                # 简单的ping检查
                return True
            
            return False
            
        except Exception as e:
            logger.error(f"性能监控仪表板健康检查失败: {e}")
            return False
    
    def get_metrics_count(self) -> int:
        """获取指标数量"""
        try:
            if self.metrics_collector and hasattr(self.metrics_collector, 'get_metrics_count'):
                return self.metrics_collector.get_metrics_count()
            return 0
        except Exception:
            return 0
    
    def get_active_alerts_count(self) -> int:
        """获取活跃告警数量"""
        try:
            if self.dashboard and hasattr(self.dashboard, 'get_active_alerts_count'):
                return self.dashboard.get_active_alerts_count()
            return 0
        except Exception:
            return 0


# 全局服务实例
performance_dashboard_service = PerformanceDashboardService()


async def get_performance_dashboard_service() -> PerformanceDashboardService:
    """获取性能监控仪表板服务实例"""
    return performance_dashboard_service